using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;
using System.Data.SQLite;

namespace Common
{
        /// <summary>
        /// Helper class that makes it easier to work with the provider.
        /// </summary>
        public sealed class SQLiteHelper
        {
            static SQLiteHelper()
            {
                //if (System.Configuration.ConfigurationManager.AppSettings["dbFile"] != null)
                //    _connectionString = System.Configuration.ConfigurationManager.AppSettings["dbFile"];

                //_connectionString = @"Data Source=G:\MyGame\virus\Virus\db\db.s3db";
            }
            private static string _connectionString = @"Data Source=db.s3db";

            public static string ConnectionString
            {
                get {
                    return SQLiteHelper._connectionString;
                }
                set { SQLiteHelper._connectionString = value; }
            }

            // this class provides only static methods
            private SQLiteHelper()
            {
            }

            #region ExecuteNonQuery

            /// <summary>
            /// Executes a single command against a SQLite database.  The <see cref="IDbConnection"/> is assumed to be
            /// open when the method is called and remains open after the method completes.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use</param>
            /// <param name="commandText">SQL command to be executed</param>
            /// <param name="commandParameters">Array of <see cref="IDataParameter"/> objects to use with the command.</param>
            /// <returns></returns>
            public static int ExecuteNonQuery(
                IDbConnection connection,
                string commandText,
                params IDataParameter[] commandParameters)
            {
                //create a command and prepare it for execution
                SQLiteCommand cmd = new SQLiteCommand();
                cmd.Connection = (SQLiteConnection)connection;
                cmd.CommandText = commandText;
                System.Diagnostics.Debug.WriteLine(commandText);
                cmd.CommandType = CommandType.Text;

                if (commandParameters != null)
                    foreach (IDataParameter p in commandParameters)
                    {
                        //if (p.DbType == DbType.DateTime)
                        //{
                        //    p.DbType = DbType.String;
                        //    p.Value = ((DateTime)p.Value).ToString("yyyy-MM-dd HH:mm:ss");
                        //}
                        cmd.Parameters.Add(p);
                    }

                int result = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();

                return result;
            }

            /// <summary>
            /// Executes a single command against a SQLite database.  A new <see cref="IDbConnection"/> is created
            /// using the <see cref="IDbConnection.ConnectionString"/> given.
            /// </summary>
            /// <param name="connectionString"><see cref="IDbConnection.ConnectionString"/> to use</param>
            /// <param name="commandText">SQL command to be executed</param>
            /// <param name="parms">Array of <see cref="IDataParameter"/> objects to use with the command.</param>
            /// <returns></returns>
            public static int ExecuteNonQuery(
                string connectionString,
                string commandText,
                params IDataParameter[] parms)
            {
                //create & open a SqlConnection, and dispose of it after we are done.
                using (SQLiteConnection cn = new SQLiteConnection(connectionString))
                {
                    cn.Open();

                    //call the overload that takes a connection in place of the connection string
                    return ExecuteNonQuery(cn, commandText, parms);
                }
            }

            public static int ExecuteNonQuery(
                string commandText,
                params IDataParameter[] parms)
            {
                //create & open a SqlConnection, and dispose of it after we are done.
                using (SQLiteConnection cn = new SQLiteConnection(ConnectionString))
                {
                    cn.Open();

                    //call the overload that takes a connection in place of the connection string
                    return ExecuteNonQuery(cn, commandText, parms);
                }
            }
            #endregion

            #region ExecuteDataSet

            /// <summary>
            /// Executes a single SQL command and returns the first row of the resultset.  A new IDbConnection object
            /// is created, opened, and closed during this method.
            /// </summary>
            /// <param name="connectionString">Settings to be used for the connection</param>
            /// <param name="commandText">Command to execute</param>
            /// <param name="parms">Parameters to use for the command</param>
            /// <returns>DataRow containing the first row of the resultset</returns>
            public static DataRow ExecuteDataRow(string connectionString, string commandText, params IDataParameter[] parms)
            {
                DataSet ds = ExecuteDataset(connectionString, commandText, parms);
                if (ds == null) return null;
                if (ds.Tables.Count == 0) return null;
                if (ds.Tables[0].Rows.Count == 0) return null;
                return ds.Tables[0].Rows[0];
            }

            /// <summary>
            /// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.  
            /// A new IDbConnection object is created, opened, and closed during this method.
            /// </summary>
            /// <param name="connectionString">Settings to be used for the connection</param>
            /// <param name="commandText">Command to execute</param>
            /// <returns><see cref="DataSet"/> containing the resultset</returns>
            public static DataSet ExecuteDataset(string connectionString, string commandText)
            {
                //pass through the call providing null for the set of SqlParameters
                return ExecuteDataset(connectionString, commandText, (IDataParameter[])null);
            }

            public static DataSet ExecuteDataset(string commandText)
            {
                //pass through the call providing null for the set of SqlParameters
                return ExecuteDataset(ConnectionString, commandText, (IDataParameter[])null);
            }

            /// <summary>
            /// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.  
            /// A new IDbConnection object is created, opened, and closed during this method.
            /// </summary>
            /// <param name="connectionString">Settings to be used for the connection</param>
            /// <param name="commandText">Command to execute</param>
            /// <param name="commandParameters">Parameters to use for the command</param>
            /// <returns><see cref="DataSet"/> containing the resultset</returns>
            public static DataSet ExecuteDataset(string connectionString, string commandText, params IDataParameter[] commandParameters)
            {
                //create & open a SqlConnection, and dispose of it after we are done.
                using (SQLiteConnection cn = new SQLiteConnection(connectionString))
                {
                    cn.Open();

                    //call the overload that takes a connection in place of the connection string
                    return ExecuteDataset(cn, commandText, commandParameters);
                }
            }

            /// <summary>
            /// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.  
            /// A new IDbConnection object is created, opened, and closed during this method.
            /// </summary>
            /// <param name="connectionString">Settings to be used for the connection</param>
            /// <param name="commandText">Command to execute</param>
            /// <param name="commandParameters">Parameters to use for the command</param>
            /// <returns><see cref="DataSet"/> containing the resultset</returns>
            public static DataSet ExecuteDataset(string commandText, params IDataParameter[] commandParameters)
            {
                //create & open a SqlConnection, and dispose of it after we are done.
                using (SQLiteConnection cn = new SQLiteConnection(ConnectionString))
                {
                    cn.Open();

                    //call the overload that takes a connection in place of the connection string
                    return ExecuteDataset(cn, commandText, commandParameters);
                }
            }


            /// <summary>
            /// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.  
            /// The state of the <see cref="IDbConnection"/> object remains unchanged after execution
            /// of this method.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use</param>
            /// <param name="commandText">Command to execute</param>
            /// <returns><see cref="DataSet"/> containing the resultset</returns>
            public static DataSet ExecuteDataset(IDbConnection connection, string commandText)
            {
                //pass through the call providing null for the set of SqlParameters
                return ExecuteDataset(connection, commandText, (IDataParameter[])null);
            }

            /// <summary>
            /// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.  
            /// The state of the <see cref="IDbConnection"/> object remains unchanged after execution
            /// of this method.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use</param>
            /// <param name="commandText">Command to execute</param>
            /// <param name="commandParameters">Parameters to use for the command</param>
            /// <returns><see cref="DataSet"/> containing the resultset</returns>
            public static DataSet ExecuteDataset(IDbConnection connection, string commandText, params IDataParameter[] commandParameters)
            {
                //create a command and prepare it for execution
                SQLiteCommand cmd = new SQLiteCommand();
                cmd.Connection = (SQLiteConnection)connection;
                cmd.CommandText = commandText;
                System.Diagnostics.Debug.WriteLine(commandText);
                cmd.CommandType = CommandType.Text;

                if (commandParameters != null)
                    foreach (IDataParameter p in commandParameters)
                    {
                        //if (p.DbType == DbType.DateTime) {
                        //    p.DbType = DbType.String;						
                        //    p.Value = ((DateTime)p.Value).ToString("yyyy-MM-dd HH:mm:ss");
                        //}
                        cmd.Parameters.Add(p);
                    }

                //create the DataAdapter & DataSet
                SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
                DataSet ds = new DataSet();

                //fill the DataSet using default values for DataTable names, etc.
                //da.FillSchema(ds, SchemaType.Source);
                da.Fill(ds);
                if (ds.Tables.Count == 0)
                {
                    da.FillSchema(ds, SchemaType.Source);
                }

                // detach the IDataParameters from the command object, so they can be used again.			
                cmd.Parameters.Clear();

                //return the dataset
                return ds;
            }

            /// <summary>
            /// Updates the given table with data from the given <see cref="DataSet"/>
            /// </summary>
            /// <param name="connectionString">Settings to use for the update</param>
            /// <param name="commandText">Command text to use for the update</param>
            /// <param name="ds"><see cref="DataSet"/> containing the new data to use in the update</param>
            /// <param name="tablename">Tablename in the dataset to update</param>
            public static void UpdateDataSet(string connectionString, string commandText, DataSet ds, string tablename)
            {
                SQLiteConnection cn = new SQLiteConnection(connectionString);
                cn.Open();
                SQLiteDataAdapter da = new SQLiteDataAdapter(commandText, cn);
                //SQLiteCommandBuilder cb = new SQLiteCommandBuilder( da );
                da.Update(ds, tablename);
                cn.Close();
            }

            #endregion

            #region ExecuteDataReader

            /// <summary>
            /// Executes a single command against a SQLite database, possibly inside an existing transaction.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use for the command</param>
            /// <param name="transaction"><see cref="SQLiteTransaction"/> object to use for the command</param>
            /// <param name="commandText">Command text to use</param>
            /// <param name="commandParameters">Array of <see cref="IDataParameter"/> objects to use with the command</param>
            /// <param name="ExternalConn">True if the connection should be preserved, false if not</param>
            /// <returns><see cref="IDataReader"/> object ready to read the results of the command</returns>
            private static IDataReader ExecuteReader(IDbConnection connection, SQLiteTransaction transaction, string commandText, IDataParameter[] commandParameters, bool ExternalConn)
            {
                //create a command and prepare it for execution
                SQLiteCommand cmd = new SQLiteCommand();
                cmd.Connection = (SQLiteConnection)connection;
                cmd.Transaction = transaction;
                cmd.CommandText = commandText;
                System.Diagnostics.Debug.WriteLine(commandText);
                cmd.CommandType = CommandType.Text;

                if (commandParameters != null)
                    foreach (IDataParameter p in commandParameters)
                    {
                        //if (p.DbType == DbType.DateTime) 
                        //{
                        //    p.DbType = DbType.String;						
                        //    p.Value = ((DateTime)p.Value).ToString("yyyy-MM-dd HH:mm:ss");
                        //}
                        cmd.Parameters.Add(p);
                    }

                //create a reader
                IDataReader dr;

                // call ExecuteReader with the appropriate CommandBehavior
                if (ExternalConn)
                {
                    dr = cmd.ExecuteReader();
                }
                else
                {
                    dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }

                // detach the SqlParameters from the command object, so they can be used again.
                cmd.Parameters.Clear();

                return dr;
            }

            /// <summary>
            /// Executes a single command against a SQLite database.
            /// </summary>
            /// <param name="connectionString">Settings to use for this command</param>
            /// <param name="commandText">Command text to use</param>
            /// <returns><see cref="IDataReader"/> object ready to read the results of the command</returns>
            public static IDataReader ExecuteReader(
                string connectionString,
                string commandText)
            {
                //pass through the call providing null for the set of SqlParameters
                return ExecuteReader(
                    connectionString,
                    commandText,
                    (IDataParameter[])null);
            }

            /// <summary>
            /// Executes a single command against a SQLite database.
            /// </summary>
            /// <param name="connectionString">Settings to use for this command</param>
            /// <param name="commandText">Command text to use</param>
            /// <param name="commandParameters">Array of <see cref="IDataParameter"/> objects to use with the command</param>
            /// <returns><see cref="IDataReader"/> object ready to read the results of the command</returns>
            public static IDataReader ExecuteReader(
                string connectionString,
                string commandText,
                params IDataParameter[] commandParameters)
            {
                //create & open a SqlConnection
                SQLiteConnection cn = new SQLiteConnection(connectionString);
                cn.Open();

                try
                {
                    //call the private overload that takes an internally owned connection in place of the connection string
                    return ExecuteReader(
                        cn, null, commandText, commandParameters, false);
                }
                catch
                {
                    //if we fail to return the SqlDatReader, we need to close the connection ourselves
                    cn.Close();
                    throw;
                }
            }
            /// <summary>
            /// Executes a single command against a SQLite database.
            /// </summary>
            /// <param name="connectionString">Settings to use for this command</param>
            /// <param name="commandText">Command text to use</param>
            /// <param name="commandParameters">Array of <see cref="IDataParameter"/> objects to use with the command</param>
            /// <returns><see cref="IDataReader"/> object ready to read the results of the command</returns>
            public static IDataReader ExecuteReader(
                string commandText,
                params IDataParameter[] commandParameters)
            {
                //create & open a SqlConnection
                SQLiteConnection cn = new SQLiteConnection(ConnectionString);
                cn.Open();

                try
                {
                    //call the private overload that takes an internally owned connection in place of the connection string
                    return ExecuteReader(
                        cn, null, commandText, commandParameters, false);
                }
                catch
                {
                    //if we fail to return the SqlDatReader, we need to close the connection ourselves
                    cn.Close();
                    throw;
                }
            }
            #endregion

            #region ExecuteScalar

            /// <summary>
            /// Execute a single command against a SQLite database.
            /// </summary>
            /// <param name="connectionString">Settings to use for the update</param>
            /// <param name="commandText">Command text to use for the update</param>
            /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
            public static object ExecuteScalar(
                string connectionString,
                string commandText)
            {
                //pass through the call providing null for the set of IDataParameters
                return ExecuteScalar(
                    connectionString,
                    commandText,
                    (IDataParameter[])null);
            }

            /// <summary>
            /// Execute a single command against a SQLite database.
            /// </summary>
            /// <param name="connectionString">Settings to use for the command</param>
            /// <param name="commandText">Command text to use for the command</param>
            /// <param name="commandParameters">Parameters to use for the command</param>
            /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
            public static object ExecuteScalar(
                string connectionString,
                string commandText,
                params IDataParameter[] commandParameters)
            {
                //create & open a SqlConnection, and dispose of it after we are done.
                using (SQLiteConnection cn = new SQLiteConnection(connectionString))
                {
                    cn.Open();

                    //call the overload that takes a connection in place of the connection string
                    return ExecuteScalar(cn, commandText, commandParameters);
                }
            }

            /// <summary>
            /// Execute a single command against a SQLite database.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use</param>
            /// <param name="commandText">Command text to use for the command</param>
            /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
            public static object ExecuteScalar(IDbConnection connection, string commandText)
            {
                //pass through the call providing null for the set of IDataParameters
                return ExecuteScalar(connection, commandText, (IDataParameter[])null);
            }

            /// <summary>
            /// Execute a single command against a SQLite database.
            /// </summary>
            /// <param name="connection"><see cref="IDbConnection"/> object to use</param>
            /// <param name="commandText">Command text to use for the command</param>
            /// <param name="commandParameters">Parameters to use for the command</param>
            /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
            public static object ExecuteScalar(IDbConnection connection, string commandText, params IDataParameter[] commandParameters)
            {
                //create a command and prepare it for execution
                SQLiteCommand cmd = new SQLiteCommand();
                cmd.Connection = (SQLiteConnection)connection;
                cmd.CommandText = commandText;
                System.Diagnostics.Debug.WriteLine(commandText);
                cmd.CommandType = CommandType.Text;

                if (commandParameters != null)
                    foreach (IDataParameter p in commandParameters)
                    {
                        //if (p.DbType == DbType.DateTime)
                        //{
                        //    p.DbType = DbType.String;						
                        //    p.Value = ((DateTime)p.Value).ToString("yyyy-MM-dd HH:mm:ss");
                        //}
                        cmd.Parameters.Add(p);
                    }

                //execute the command & return the results
                object retval = cmd.ExecuteScalar();

                // detach the SqlParameters from the command object, so they can be used again.
                cmd.Parameters.Clear();
                return retval;

            }

            #endregion
        }
    }


    /*
    public class SQLiteHelper : IDisposable
    {
        private SQLiteConnection _connection;
        private string _dataSource = string.Empty;
        private static SQLiteHelper _instance = new SQLiteHelper();
        private bool _isFirstUse;
        private Dictionary<int, SQLiteTransaction> _localTransactionCollection;
        private static object _locker = new object();
        private string _password = string.Empty;
        private static int _refCount = 0;
        private const string CONNECTION_STRING_FORMAT = "Data Source={0};Password={1}";
        private const string DATABASE_NAME = "FXRobot.dat";

        private SQLiteHelper()
        {

        }

        public void CommitTransaction()
        {
            lock (_locker)
            {
                int managedThreadId = Thread.CurrentThread.ManagedThreadId;
                if (this.LocalTransactionCollection.ContainsKey(managedThreadId))
                {
                    this.LocalTransactionCollection[managedThreadId].Commit();
                    _refCount--;
                    this.LocalTransactionCollection.Remove(managedThreadId);
                    if (_refCount == 0)
                    {
                        this._connection.Close();
                    }
                }
            }
        }

        public SQLiteCommand CreateCommand(string sql, params object[] parameters)
        {
            SQLiteCommand command = null;
            int managedThreadId = Thread.CurrentThread.ManagedThreadId;
            if (this.LocalTransactionCollection.ContainsKey(managedThreadId) && (this.LocalTransactionCollection[managedThreadId] != null))
            {
                command = new SQLiteCommand(sql, this._connection, this.LocalTransactionCollection[managedThreadId]);
            }
            else
            {
                command = new SQLiteCommand(sql, this._connection);
            }
            if (parameters != null)
            {
                foreach (SQLiteParameter parameter in this.DeriveParameters(sql, parameters))
                {
                    command.Parameters.Add(parameter);
                }
            }
            return command;
        }

        public List<SQLiteParameter> DeriveParameters(string commandText, object[] paramList)
        {
            if (paramList == null)
            {
                return null;
            }
            List<SQLiteParameter> list = new List<SQLiteParameter>();
            string input = commandText.Substring(commandText.IndexOf("@")).Replace(",", " ,").Replace(")", " )");
            string pattern = @"(@)\S*(.*?)\b";
            MatchCollection matchs = new Regex(pattern, RegexOptions.IgnoreCase).Matches(input);
            List<string> list2 = new List<string>();
            foreach (Match match in matchs)
            {
                if (!list2.Contains(match.Value))
                {
                    list2.Add(match.Value);
                }
            }
            string[] strArray = list2.ToArray();
            int index = 0;
            Type type = null;
            foreach (object obj2 in paramList)
            {
                if (obj2 == null)
                {
                    SQLiteParameter item = new SQLiteParameter();
                    item.DbType = DbType.Object;
                    item.ParameterName = strArray[index];
                    item.Value = DBNull.Value;
                    list.Add(item);
                }
                else
                {
                    type = obj2.GetType();
                    SQLiteParameter parameter2 = new SQLiteParameter();
                    switch (type.ToString())
                    {
                        case "System.String":
                            parameter2.DbType = DbType.String;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (string)paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Byte[]":
                            parameter2.DbType = DbType.Binary;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (byte[])paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Int64":
                            parameter2.DbType = DbType.Int64;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (long)paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Int32":
                            parameter2.DbType = DbType.Int32;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (int)paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Boolean":
                            parameter2.DbType = DbType.Boolean;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (bool)paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.DateTime":
                            parameter2.DbType = DbType.DateTime;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = Convert.ToDateTime(paramList[index]);
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Double":
                            parameter2.DbType = DbType.Double;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = Convert.ToDouble(paramList[index]);
                            list.Add(parameter2);
                            goto Label_0408;

                        case "System.Decimal":
                            parameter2.DbType = DbType.Decimal;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = Convert.ToDecimal(paramList[index]);
                            goto Label_0408;

                        case "System.Guid":
                            parameter2.DbType = DbType.Guid;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = (Guid)paramList[index];
                            goto Label_0408;

                        case "System.Object":
                            parameter2.DbType = DbType.Object;
                            parameter2.ParameterName = strArray[index];
                            parameter2.Value = paramList[index];
                            list.Add(parameter2);
                            goto Label_0408;
                    }
                    throw new SystemException("Value is of unknown data type");
                }
            Label_0408:
                index++;
            }
            return list;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposed)
        {
            try
            {
                if (disposed)
                {
                    if (this._localTransactionCollection != null)
                    {
                        lock (_locker)
                        {
                            foreach (SQLiteTransaction transaction in this._localTransactionCollection.Values)
                            {
                                try
                                {
                                    transaction.Rollback();
                                    transaction.Dispose();
                                    continue;
                                }
                                catch
                                {
                                    continue;
                                }
                            }
                            this._localTransactionCollection.Clear();
                            this._localTransactionCollection = null;
                        }
                    }
                    if (this._connection != null)
                    {
                        this._connection.Close();
                        this._connection.Dispose();
                    }
                }
            }
            catch
            {
            }
            finally
            {
                this._connection = null;
            }
        }

        public void EnableConnection()
        {
            if (this._connection == null)
            {
                string connectionString = string.Format("Data Source={0};Password={1}", this._dataSource, this._password);
                this._connection = new SQLiteConnection(connectionString);
            }
            if (this._connection.State == ConnectionState.Closed)
            {
                this._connection.Open();
            }
        }

        public int ExecuteNonQuery(string sql, params object[] parameters)
        {
            this.EnableConnection();
            return this.CreateCommand(sql, parameters).ExecuteNonQuery();
        }

        public SQLiteDataReader ExecuteReader(string sql, params object[] parameters)
        {
            this.EnableConnection();
            return this.CreateCommand(sql, parameters).ExecuteReader();
        }

        public int ExecuteScalar(string sql, params object[] parameters)
        {
            this.EnableConnection();
            object obj2 = this.CreateCommand(sql, parameters).ExecuteScalar();
            if (obj2 != null)
            {
                return int.Parse(obj2.ToString());
            }
            return 0;
        }

        ~SQLiteHelper()
        {
            this.Dispose(false);
        }

        public bool InitializeDatabase(string currentUserSid)
        {
            bool flag;
            lock (_locker)
            {
                if (!this.Disposed)
                {
                    this.Dispose();
                }
                string app = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                app = Path.Combine(app, "Fetion");
                string path = Path.Combine(app, currentUserSid);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                this._dataSource = Path.Combine(path, DATABASE_NAME);
                this._password = currentUserSid;
                this._localTransactionCollection = new Dictionary<int, SQLiteTransaction>();
                try
                {
                    if (!File.Exists(this._dataSource))
                    {
                        SQLiteConnection.CreateFile(this._dataSource);
                        string connectionString = string.Format("Data Source={0};Password={1}", this._dataSource, this._password);
                        this._connection = new SQLiteConnection(connectionString);
                        this._connection.SetPassword(this._password);
                    }
                    flag = true;
                }
                catch
                {
                    this.Dispose();
                    File.Delete(this._dataSource);
                    flag = false;
                }
            }
            return flag;
        }

        public void JoinTransaction()
        {
            lock (_locker)
            {
                this.EnableConnection();
                _refCount++;
                int managedThreadId = Thread.CurrentThread.ManagedThreadId;
                if (!this.LocalTransactionCollection.ContainsKey(managedThreadId))
                {
                    this.LocalTransactionCollection.Add(managedThreadId, this._connection.BeginTransaction());
                }
            }
        }

        public void RollbackTransaction()
        {
            lock (_locker)
            {
                int managedThreadId = Thread.CurrentThread.ManagedThreadId;
                if (this.LocalTransactionCollection.ContainsKey(managedThreadId))
                {
                    this.LocalTransactionCollection[managedThreadId].Rollback();
                    _refCount--;
                    this.LocalTransactionCollection.Remove(managedThreadId);
                    if (_refCount == 0)
                    {
                        this._connection.Close();
                    }
                }
            }
        }

        public bool Disposed
        {
            get
            {
                return (this._connection != null);
            }
        }

        public static SQLiteHelper Instance
        {
            get
            {
                return _instance;
            }
        }

        public bool IsFirstUse
        {
            get
            {
                return this._isFirstUse;
            }
        }

        private Dictionary<int, SQLiteTransaction> LocalTransactionCollection
        {
            get
            {
                lock (_locker)
                {
                    if (this._localTransactionCollection == null)
                    {
                        this._localTransactionCollection = new Dictionary<int, SQLiteTransaction>();
                    }
                    return this._localTransactionCollection;
                }
            }
        }

        public List<string> Objects
        {
            get
            {
                lock (_locker)
                {
                    List<string> list = new List<string>();
                    using (SQLiteDataReader reader = this.ExecuteReader("SELECT [Name] FROM [SQLITE_MASTER] WHERE ([type] = 'table') OR ([type] = 'view')", null))
                    {
                        while (reader.Read())
                        {
                            list.Add(reader["name"].ToString());
                        }
                    }
                    return list;
                }
            }
        }
    }
     * */

